package jmine.tec.test.i18n;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

/**
 * Utilitary class that creates enum declarations corresponding to messages in a bundle.
 * 
 * @author lundberg
 */
public class MessageCreatorCreator {

    /**
     * Creates enum declarations for messages in a bundle
     * 
     * @param bundleName bundleName
     * @return List of enum declarations
     * @throws Exception Exception
     */
    public List<String> create(String bundleName) throws Exception {
        Properties properties = new Properties();
        properties.load(this.getClass().getClassLoader().getResourceAsStream(bundleName));
        List<String> messages = new ArrayList<String>();
        for (Object key : properties.keySet()) {
            String messageEnum = this.keyToEnum(key.toString());
            int arguments = this.countArguments(properties.get(key).toString());
            messages.add(String.format("%s(%s, \"%s\")", messageEnum, arguments, key));
        }
        return messages;
    }

    /**
     * Counts the number of arguments required by the message
     * 
     * @param message message
     * @return argument count
     */
    private int countArguments(String message) {
        Matcher matcher = Pattern.compile("\\{\\d+\\}").matcher(message);
        int matches = 0;
        while (matcher.find()) {
            matches++;
        }
        return matches;
    }

    /**
     * Creates an enum name based on the message key
     * 
     * @param key key
     * @return String
     */
    private String keyToEnum(String key) {
        List<String> parts = new ArrayList<String>();
        for (String dotPart : Arrays.asList(key.split("\\."))) {
            Matcher matcher = Pattern.compile("([a-z]+|[A-Z]+[a-z]*)").matcher(dotPart);
            while (matcher.find()) {
                parts.add(matcher.group(1).toUpperCase());
            }
        }
        return StringUtils.join(parts, "_");
    }
}
